package com.asm.protocol;

import com.asm.rpc.source.TestGson;
import com.google.gson.*;

import java.io.*;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

/**
 * 用于扩展序列化，反序列化算法
 *
 * */
public interface MySerializer {
    //反序列化方法
    <T> T deserialize(Class<T>clazz,byte[] bytes);

    //序列化方法
    <T>byte[] serialize(T object);

    //使用枚举实现方法
    enum Algorithm implements MySerializer {
        /**
         * 多个算法
         * 枚举对象.ordinal() 获取顺序int， 第一个0 第二个1 ...
         */
   Java{
       @Override
       public <T> T deserialize(Class<T> clazz, byte[] bytes) {
           try {
               // 处理内容
               final ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
               final ObjectInputStream ois = new ObjectInputStream(bis);

               // 转成 Message类型
               T message = (T) ois.readObject();

               return message;
           } catch (IOException | ClassNotFoundException e) {

               throw new RuntimeException("反序列化算法失败！");
           }
       }

       @Override
       public <T> byte[] serialize(T object) {
          // System.out.println("对象流算法---加密");
           try {
               // 处理内容 用对象流包装字节数组 并写入
               ByteArrayOutputStream bos = new ByteArrayOutputStream(); // 访问数组
               ObjectOutputStream oos = new ObjectOutputStream(bos);    // 用对象流 包装
               oos.writeObject(object);

               return bos.toByteArray();

           } catch (IOException e) {
               throw new RuntimeException("序列化算法失败！", e);
           }
       }
       },

    Json{
           @Override
           public <T> T deserialize(Class<T> clazz, byte[] bytes) {
               Gson gson = new GsonBuilder().registerTypeAdapter(Class.class, new classCodec()).create();
               String json = new String(bytes, StandardCharsets.UTF_8);
               return gson.fromJson(json,clazz);
           }

           @Override
           public <T> byte[] serialize(T object) {
               Gson gson = new GsonBuilder().registerTypeAdapter(Class.class, new classCodec()).create();
               String json = gson.toJson(object);
               return json.getBytes(StandardCharsets.UTF_8);
           }
       }
   }

    }


 class classCodec implements JsonSerializer<Class<?>>, JsonDeserializer<Class<?>> {

    @Override//反序列化
    public Class<?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {

        try {
            //拿到类名
            String str = json.getAsString();
            //forName通过类名转成class
            return Class.forName(str);
        } catch (ClassNotFoundException e) {
            throw new JsonParseException(e);
        }
    }

    @Override  //string.class  //序列化
    public JsonElement serialize(Class<?> src, Type type, JsonSerializationContext jsonSerializationContext) {
        //class字节码 -> json

        return new JsonPrimitive(src.getName());
    }
}

